Виджеты. Container Особенности
➡️ Ссылка на репозиторий с кодом этого урока
Container Особенности Поведения
❗️Изучение материала требует подготовки
К этой теме следует вернуться после изучения базовых виджетов и после самостоятельной верстки нескольких простых макетов.
Файл main.dart
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: "Flutter Course",
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
),
home: Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text("Виджет Container"),
),
body: ContainerExample() // 🡰 Сюда
),
);
}
}
Создание базового контейнера
Добавим в папку widgets файл ex_container.dart
Виджет Container
Это универсальный строительный виджет во Flutter, который позволяет гибко управлять внешним видом элементов, как блок <div> в веб-разработке. Container объединяет в себе возможности настройки фона, размеров, позиционирования, отступов и границ.
Container вмещает только одного дочернего элемента child, но этот элемент может содержать другие компоненты, создавая сложные иерархии.
Container это блочный элемент, по сути прямоугольник с определенными свойствами, такими как цвет фона, границы и отступы (внутренние и внешние).
Для создания базового контейнера, мы можем определить несколько свойств, таких как color, width, height, padding и margin. Например, создадим контейнер с голубым фоном, шириной 200 и высотой 200
Container(
color: Colors.blue,
width: 200,
height: 200,
)
Основные свойства
alignment → выравнивание ДОЧЕРНЕГО элемента
child → дочерний элемент
color → цвет фона контейнера (не использовать если задан параметр decoration)
constraints → дополнительные ограничения размера для ДОЧЕРНЕГО элемента
decoration → фоновое оформление контейнера
foregroundDecoration → поверхностное оформление, рисуется поверх child
width → ширина контейнера
height → высота контейнера
margin → отступы вокруг контейнера
padding → поля внутри контейнера
transform → матричное преобразование геометрии контейнера
Добавление границ
Можно добавить границы к контейнеру с помощью свойства border
import 'package:flutter/material.dart';
class ContainerExample extends StatelessWidget {
const ContainerExample({super.key});
@override
Widget build(BuildContext context) {
return Center(
child: Container(
// Ошибка! Нельзя одновременно использовать color и decoration
// color: Colors.blue,
width: 200,
height: 200,
decoration: BoxDecoration(
color: Colors.blue,
border: Border.all(
// Добавить границы со всех сторон
color: Colors.black,
width: 5,
),
),
),
);
}
}

Важно!
При использовании BoxDecoration, цвет фона color задается внутри свойства decoration, а не в color контейнера!!! Иначе будет ошибка отрисовки
.png)
Добавление отступов
Можно добавить отступы к контейнеру, с помощью свойств paddingили margin
Сделаем контейнер с фоном, шириной 200, высотой 200 и с отступами по 20 пикселей
class ContainerExample extends StatelessWidget {
const ContainerExample({super.key});
@override
Widget build(BuildContext context) {
return Container(
width: 200,
height: 200,
// Внешние отступы от границ контейнера
margin: const EdgeInsets.all(20.0),
// Внутренние отступы от содержимого
padding: const EdgeInsets.all(20.0),
decoration: BoxDecoration(
color: Colors.blue,
border: Border.all(color: Colors.black, width: 5),
),
child: const Text(
"Container",
style: TextStyle(
color: Colors.white,
fontSize: 18.0,
fontWeight: FontWeight.bold,
),
),
);
}
}
Рассмотрим подробно все параметры виджета для создания отступов:
// Задать одинаковые отступы со всех сторон
padding: const EdgeInsets.all(20.0),
// Задать отступы конкретно для каждой стороны
// Следование такое: Left, Top, Right, Bottom
padding: const EdgeInsets.fromLTRB(20.0, 10.0, 20.0, 10.0),
// Задать отступ конкретно для какой-то стороны, или нескольких сторон
padding: const EdgeInsets.only(top: 20.0),
padding: const EdgeInsets.only(right: 20.0),
padding: const EdgeInsets.only(bottom: 20.0),
padding: const EdgeInsets.only(left: 20.0),
// Задать отступы симметрично горизонтально или вертикально
padding: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 20.0),
Примеры поведения Container
1 - Контейнер занимает всё доступное пространство
Контейнер занимает доступное ему пространство
- Контейнер растянется до родителя, если у него нет
child - Если родитель это
Scaffold, то размер будет на весь экран - Если у родителя есть свои размеры, то до размеров этого родителя
class ContainerExample1 extends StatelessWidget {
const ContainerExample1({super.key});
@override
Widget build(BuildContext context) {
return Container(color: Colors.blue[100]);
// Размеры родителя 150 на 150
// body: SizedBox(
// width: 150,
// height: 150,
// child: Container(
// color: Colors.blue[100],
// ),
// ),
}
}
.png)
2 - Контейнер принимает размер дочернего элемента
Контейнер принимает размер дочернего элемента.
Если у Container нет родителя, но есть child, то Container ужмётся до размеров своего child
class ContainerExample2 extends StatelessWidget {
const ContainerExample2({super.key});
@override
Widget build(BuildContext context) {
return Center(
child: Container(
color: Colors.blue[100],
child: const Text(
'IT-Квантум',
style: TextStyle(fontSize: 40.0, fontWeight: FontWeight.bold),
),
),
);
}
}
.png)
3 - Контейнер принимает размеры ограничений
Высоту и ширину можно регулировать вручную
-
Размеры контейнера 100% по отношению к родительскому элементу
-
Если Родитель
не указываетограничения размеров, то- Если
Containerимеетchild, то он ужимается до него - Если
Containerимеетheightиwidth, то он применяет эти значения
- Если
-
Если Родитель
указывает ограниченияразмеров, тоContainerпринимает эти размеры, даже если внутриContainerуказаны вручную значенияwidthиheight
Вариант 1 - когда у Container нет родителя, но есть свои width height и child
class ContainerExample3 extends StatelessWidget {
const ContainerExample3({super.key});
@override
Widget build(BuildContext context) {
return Container(
// Высоту и ширину можно регулировать вручную
width: double.infinity, // Макс. возможная ширина
height: 200.0,
color: Colors.blue[100],
child: const Text(
'IT-Квантум',
style: TextStyle(fontSize: 24.0, fontWeight: FontWeight.bold),
),
);
}
}
.png)
Вариант 2 - когда у Container есть родитель со своими ограничениями размеров.
Так же у Container есть свои width height и child
class ContainerExample3 extends StatelessWidget {
const ContainerExample3({super.key});
@override
Widget build(BuildContext context) {
return SizedBox(
// Приоритет размеров родителя выше чем у вложенных виджетов
width: 150.0,
height: 100.0,
child: Container(
width: double.infinity, // Игнор этого размера
height: 200.0, // Игнор этого размера
color: Colors.blue[100],
child: const Text(
'IT-Квантум',
style: TextStyle(fontSize: 24.0, fontWeight: FontWeight.bold),
),
),
);
}
}
.png)
4 - Выравнивание дочернего элемента контейнера
Alignment - eсли добавить для child контейнера выравнение (alignment), то контейнер растянется до своего родителя !
Расположение по умолчанию - если Alignment не указано, child всегда будет располагаться в верхнем-левом углу контейнера
class ContainerExample4 extends StatelessWidget {
const ContainerExample4({super.key});
@override
Widget build(BuildContext context) {
return Container(
// Ширина контейнера 100% родителя
width: double.infinity,
height: 200.0,
// Дочерний элемент по центру
alignment: Alignment.center,
color: Colors.blue[100],
child: const Text('IT-Квантум'),
);
}
}
Поведение работы выравнивания
На 1 изображении у контейнера ЕСТЬ width и height, указано alignment
На 2 изображении у контейнера НЕТ width и height, указано alignment
На 3 изображении у контейнера ЕСТЬ width и height, НЕ указано alignment
.png)
Значения Alignment
.png)
Alignment имеет несколько положений где может находится child
Можно более точно указать положение через координаты, например
Alignment(-1,1)
Alignment(-0.1,1)
Alignment(0.02,-0.5)
5 - Контейнер с максимальной шириной, отступами и фоном
Единицы размеров Flutter виджетов
Размеры элементов, такие как ширина и высота, указываются в logical pixels логических пикселях
height: 200.0
Логические пиксели - это абстрактная единица измерения, которая позволяет создавать интерфейсы, которые выглядят одинаково на устройствах с разными плотностями пикселей.
Логические пиксели автоматически масштабируются в зависимости от плотности пикселей устройства, на котором работает приложение.
Например, на устройстве с плотностью пикселей 1x (например, старые смартфоны) 200 логических пикселей будут соответствовать 200 физическим пикселям. На устройстве с плотностью пикселей 2x (например, современные смартфоны) 200 логических пикселей будут соответствовать 400 физическим пикселям, и так далее.
class ContainerExample5 extends StatelessWidget {
const ContainerExample5({super.key});
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity, // Ширина контейнера 100% родителя
height: 200.0, // Высота контейнера 100
padding: const EdgeInsets.all(32.0), // внутренние отступы
margin: const EdgeInsets.all(32.0), // внешние отступы
color: Colors.blue[100], // Цвет фона контейнера
child: const Text(
'IT-Квантум',
style: TextStyle(fontSize: 24.0, fontWeight: FontWeight.bold),
),
);
}
}
.png)
6 - Фоновое изображение контейнера
class ContainerExample6 extends StatelessWidget {
const ContainerExample6({super.key});
@override
Widget build(BuildContext context) {
return Center(
child: Container(
width: 250.0,
height: 250.0,
alignment: Alignment.bottomRight,
// Установить фоном изображение
decoration: const BoxDecoration(
image: DecorationImage(image: AssetImage("assets/images/driada.png")),
// Сделать фигуру контейнера в виде круга
// shape: BoxShape.circle,
),
child: const Text(
'IT-Квантум в деле',
style: TextStyle(color: Colors.white, fontSize: 16.0),
),
),
);
}
}
.png)
.png)
Ключевые моменты поведения виджета Container
Ключевые моменты
-
Контейнер
БЕЗ ДОЧЕРНЕГОэлемента, иБЕЗ ОГРАНИЧЕНИЙпо ширине и высоте, занимаетВСЁдоступное пространство (на которое позволяет занять его родитель) -
Контейнер
С ДОЧЕРНИМэлементом принимаетЕГОразмер (точней выразится дочерний элемент может принимать размер, ограниченныйcontainer, а раз уContainerнет ограничений, то по сути размер будут как уchild) -
НО если
ЕСТЬ ВЫРАВНИВАНИЕ, то принимаетРАЗМЕР РОДИТЕЛЬСКОГОэлемента. -
Параметры
width,heightиconstraintsпереопределяют размер контейнера.
-
Если у виджета нет дочернего элемента, нет высоты, ширины, ограничений, а родительский элемент предоставляет неограниченные ограничения, тогда Контейнер пытается уменьшиться до как можно меньшего значения.
-
Если у виджета нет дочернего элемента и нет выравнивания, но есть высота, ширина или ограничения, тогда Контейнер пытается быть как можно меньше с учетом комбинации этих ограничений и ограничений родительского элемента.
-
Если виджет не имеет дочернего элемента, высоты, ширины, ограничений и выравнивания, но родительский элемент предоставляет ограниченные ограничения, тогда Контейнер расширяется, чтобы соответствовать ограничениям, предоставленным родительским элементом.
-
Если у виджета есть выравнивание, а родительский элемент предоставляет неограниченные ограничения, тогда Контейнер пытается установить размер вокруг дочернего элемента.
-
Если у виджета есть выравнивание, а родительский элемент предоставляет ограниченные ограничения, тогда Контейнер пытается развернуться, чтобы соответствовать родителю, а затем размещает дочерний элемент внутри себя в соответствии с выравниванием.
-
Если у виджета есть дочерний элемент, но нет высоты, ширины, ограничений и выравнивания, то Контейнер передает ограничения от родительского элемента дочернему и размеры самого себя в соответствии с дочерним элементом.
.png)
.png)
.png)